package com.xunan.demo.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;


@Slf4j
@Configuration
public class WechatPaymentConfig {

    /**
     * 微信支付商户号
     */
    @Value("${wechat-payment.merchant-id}")
    String PAYMENT_MERCHANT_ID;
    /**
     * 微信支付证书序列号
     */
    @Value("${wechat-payment.cert-serial-number}")
    String PAYMENT_CERT_SERIAL_NO;
    /**
     * 微信支付API V3秘钥
     */
    @Value("${wechat-payment.api-v3-key}")
    String PAYMENT_API_V_3_KEY;
    /**
     * 微信支付私钥证书位置
     */
    @Value("${wechat-payment.private-key-location}")
    String PAYMENT_PRIVATE_KEY_LOCATION;
    /**
     * 微信支付公钥证书位置
     */
    @Value("${wechat-payment.public-cert-location}")
    String PAYMENT_PUBLIC_CERT_LOCATION;

    /**
     * 获取商户私钥
     *
     * @return 商户私钥
     */
    @Bean
    public PrivateKey wechatMerchantPrivateKey() {
        try {
            //读取证书文件
            InputStream inputStream = this.getClass().getResourceAsStream(PAYMENT_PRIVATE_KEY_LOCATION);
            PrivateKey merchantPrivateKey;
            if (inputStream != null) {
                merchantPrivateKey = PemUtil.loadPrivateKey(inputStream);
                log.info("秘钥读取正常");
            } else {
                log.error("错误：秘钥读取为空");
                return null;
            }

            return merchantPrivateKey;
        } catch (Exception exception) {
            exception.printStackTrace();
            return null;
        }
    }

    /**
     * 获取商户公钥
     * 也可以通过Verifier中的getValidCertificate方法获取
     *
     * @return 商户公钥
     */
    @Bean
    public X509Certificate wechatMerchantPublicCert() {
        try {
            //读取证书文件
            InputStream inputStream = this.getClass().getResourceAsStream(PAYMENT_PUBLIC_CERT_LOCATION);
            X509Certificate merchantPublicCert;
            if (inputStream != null) {
                merchantPublicCert = PemUtil.loadCertificate(inputStream);
                log.info("公钥读取正常");
            } else {
                log.error("错误：公钥读取为空");
                return null;
            }

            return merchantPublicCert;
        } catch (Exception exception) {
            exception.printStackTrace();
            return null;
        }
    }

    /**
     * 获取认证器
     *
     * @return 认证器
     */
    @Bean
    public Verifier wechatVerifier() {
        try {
            //获取私钥
            PrivateKey merchantPrivateKey = wechatMerchantPrivateKey();
            if (merchantPrivateKey == null) {
                log.error("错误：获取到的秘钥为空");
                return null;
            } else {
                log.info("已成功读取秘钥");
            }

            // 获取证书管理器实例
            CertificatesManager certificatesManager = CertificatesManager.getInstance();
            //向证书管理器增加需要自动更新平台证书的商户信息
            certificatesManager.putMerchant(PAYMENT_MERCHANT_ID,
                    new WechatPay2Credentials(PAYMENT_MERCHANT_ID,
                            new PrivateKeySigner(PAYMENT_CERT_SERIAL_NO, merchantPrivateKey)),
                    PAYMENT_API_V_3_KEY.getBytes(StandardCharsets.UTF_8));

            //从证书管理器中获取merchantVerifier
            return certificatesManager.getVerifier(PAYMENT_MERCHANT_ID);
        } catch (Exception exception) {
            exception.printStackTrace();
            return null;
        }

    }

    /**
     * 微信支付HttpClient
     *
     * @return 微信支付HttpClient
     */
    @Bean
    public CloseableHttpClient wechatHttpClient() {
        Verifier merchantVerifier = wechatVerifier();
        if (merchantVerifier == null) {
            log.error("错误：获取到的Verifier为空");
            return null;
        } else {
            log.info("已成功读取Verifier");
        }

        //获取私钥
        PrivateKey merchantPrivateKey = wechatMerchantPrivateKey();
        if (merchantPrivateKey == null) {
            log.error("错误：获取到的秘钥为空");
            return null;
        } else {
            log.info("已成功读取秘钥");
        }

        //通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(PAYMENT_MERCHANT_ID, PAYMENT_CERT_SERIAL_NO, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(merchantVerifier));
        return builder.build();
    }
}
